package com.java.model.proxy;

import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;


public class TestProxyFactory {
    public static void main(String[] args) {
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(new Target1());// 设置目标对象
        // 添加通知，MethodInterceptor 是环绕通知
//        proxyFactory.addAdvice((MethodInterceptor) invocation -> {
//            try {
//                System.out.println("before...");
//                return invocation.proceed();// 调用目标
//            } finally {
//                System.out.println("after...");
//
//            }
//        });
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("execution(* foo())");
        proxyFactory.addAdvisor(new DefaultPointcutAdvisor(pointcut, (MethodInterceptor) invocation -> {
            try {
                System.out.println("before...");
                return invocation.proceed();// 调用目标
            } finally {
                System.out.println("after...");
            }
        }));

        proxyFactory.addAdvisor(new DefaultPointcutAdvisor(pointcut, (MethodInterceptor) invocation -> {
            try {
                System.out.println("before2...");
                return invocation.proceed();// 调用目标
            } finally {
                System.out.println("after2...");
            }
        }));

        proxyFactory.setProxyTargetClass(true);// 加上这个设置，不管有没有实现接口都是用CGLIB实现代理

//        Target1 proxy = (Target1) proxyFactory.getProxy();// 创建代理对象
        proxyFactory.addInterface(I1.class);
        I1 proxy = (I1) proxyFactory.getProxy();// 创建代理对象
        System.out.println(proxy.getClass());
        proxyFactory.addInterface(I1.class);
        proxy.foo();
        proxy.bar();

    }

    interface I1 {
        void foo();
        void bar();
    }

    static class Target1 implements I1 {

        @Override
        public void foo() {
            System.out.println("target1 foo");
        }

        @Override
        public void bar() {
            System.out.println("target1 bar");
        }
    }

}


